package com.hn.gege.core.conf;

import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.*;

@Configuration
@EnableSwagger2
public class Swagger2Config {
    private DefaultListableBeanFactory context;
    private RequestMappingHandlerMapping mapping;


    public Swagger2Config(DefaultListableBeanFactory context, RequestMappingHandlerMapping mapping) {
        this.context = context;
        this.mapping = mapping;
        cofig();
    }

    /**
     * 执行配置
     */
    private void cofig(){
        //添加head参数配置start
        ParameterBuilder tokenPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<Parameter>();
        tokenPar.name("Authorization").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
        pars.add(tokenPar.build());

        Set<String> pathGroup = null;
        try {
            pathGroup = getPathGroup();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        pathGroup.forEach(item -> {
            Docket enable = new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    //是否启动swagger 如果是false则不能在浏览器中使用
                    .enable(true)
                    .groupName(item)
                    .select()
                    // 在指定的包下，扫描注解
//                    .apis(Predicates.or(Swagger2Config.basePackage("com.hn.gege")))
                    .apis(RequestHandlerSelectors.basePackage("com.hn.gege"))
                    .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                    // 过滤路劲过滤（any()表示要所有扫描到的）
                    //.paths(PathSelectors.any())
                    .paths(PathSelectors.ant(item + "/**"))
                    .build()
                    .globalOperationParameters(pars);//添加请求头参数;
            context.registerSingleton("enable" + item , enable);
        });

    }

    /**
     * 对接口进行分组
     * @return
     */
    private Set<String> getPathGroup() throws ClassNotFoundException {
        HashSet<String> set = new HashSet<>();

        Map<RequestMappingInfo, HandlerMethod> mappingHandlerMethods = mapping.getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> map : mappingHandlerMethods.entrySet()) {
            HashMap<String, Object> pmap = new HashMap<>();
            RequestMappingInfo info = map.getKey();
            HandlerMethod method = map.getValue();
            PatternsRequestCondition patternsCondition = info.getPatternsCondition();
            String className = method.getMethod().getDeclaringClass().getName();
            /**
             * 匹配包路径 根据自己的路径替换
             */
            if (className.contains("com.hn.gege")) {
                for(String url : patternsCondition.getPatterns()) {
                    int i = url.indexOf("/", 1);
                    if (i<0){
                        set.add(url);
                    }else {
                        set.add(url.substring(0, i));
                    }
                }
            }
        }
        return set;
    }

    /*@Bean
    public Docket api() {
        //添加head参数配置start
        ParameterBuilder tokenPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<Parameter>();
        tokenPar.name("Authorization").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
        pars.add(tokenPar.build());

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                //是否启动swagger 如果是false则不能在浏览器中使用
                .enable(true)
                .select()
                // 在指定的包下，扫描注解
                .apis(Predicates.or(Swagger2Config.basePackage("com.hn.gege")))
                // 过滤（any()表示要所有扫描到的）
                //.paths(PathSelectors.any())
                .paths(PathSelectors.ant("/sys/**"))
                .build()
            .globalOperationParameters(pars);//添加请求头参数


    }*/
    
    /*public static Predicate<RequestHandler> basePackage(final String basePackage) {
        return new Predicate<RequestHandler>() {

            @Override
            public boolean apply(RequestHandler input) {
                return declaringClass(input).transform(handlerPackage(basePackage)).or(true);
            }
        };
    }*/
    
    /*private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
        return new Function<Class<?>, Boolean>() {
            
            @Override
            public Boolean apply(Class<?> input) {
                for (String strPackage : basePackage.split(",")) {
                    boolean isMatch = input.getPackage().getName().startsWith(strPackage);
                    if (isMatch) {
                        return true;
                    }
                }
                return false;
            }
        };
    }*/

    /*private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
        return Optional.fromNullable(input.declaringClass());
    }*/


    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("接口文档")
                .description("项目地址：http://localhost:5200/gege")
                .version("1.0")
                .build();
    }
}
